<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>接元宝</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            width: 100%;
            height: 100%;
        }
        #canvas {
            margin-left: 100px;
        }
        #score {
            margin-left: 100px;
            width: 400px;
            text-align: center;
            padding: 10px;
            height: 50px;
            box-sizing: border-box;
            font-weight: normal;
            color: orangered;
        }
        img {
            position: absolute;
            left: -100000px;
        }
    </style>
    <script>
        var ctx;
        var peopleImg;
        var boomImg;
        var yuanbao;
        var bombImg;
        var people = new People(100, 419, 10, 60, 81);
        var moneyArray = new Array();
        var boomArray = new Array();
        var bombArray = new Array();
        var moneyTimer;
        var bombTimer;
        var flashTimer;

        /** 游戏对象基类 */
        function GameObject (x, y, speed, w, h) {
            this.x = x;
            this.y = y;
            this.speed = speed;
            this.w = w;
            this.h = h;
            this.isLive = true;
        }

        function People (x, y, speed, w, h) {
            this.score = 0;
            this.gameObject = GameObject;
            this.gameObject(x, y, speed, w, h);

            this.moveLeft = function () {
                this.x = this.x - this.speed < 0 ? 0 : this.x - this.speed;
            }

            this.moveRight = function () {
                this.x = this.x + this.speed + this.w > 400 ? 400 : this.x + this.speed;
            }
        }

        function Money (x, y, speed, w, h) {
            this.gameObject = GameObject;
            this.gameObject(x, y, speed, w, h);
            this.timer = null;
            this.score = 5;
            
            this.run = function () {
                if (this.y > 500) {
                    window.clearInterval(this.timer);
                    this.isLive = false;
                } else {
                    this.y += this.speed;
                }
            }
        }

        /** 炸弹类 */
        function Bomb (x, y, speed, w, h) {
            this.gameObject = GameObject;
            this.gameObject(x, y, speed, w, h);
            this.timer = null;

            this.run = function () {
                if (this.y > 500) {
                    window.clearInterval(this.timer);
                    this.isLive = false;
                } else {
                    this.y += this.speed;
                }
            }
        }

        /** 爆炸类 */
        function Boom (x, y) {
            this.x = x;
            this.y = y;
            this.isLive = true;
            this.blood = 0;
            this.bloodUp = function () {
                if (this.blood <= 4) {
                    this.blood++;
                } else {
                    this.isLive = false;
                }
            }
        }

        /** 生成礼物 */
        function moneyFactory () {
            var money = new Money(Math.random() * (400 - 32), 0, 5, 40, 40);
            moneyArray.push(money);
            window.setInterval('moneyArray[' + (moneyArray.length - 1) + '].run()', 50);
        }


        /** 生成炸弹 */
        function bombFactory () {
            var bomb = new Bomb(Math.random() * (400 - 32), 0, 5, 40, 40);
            bombArray.push(bomb);
            window.setInterval('bombArray[' + (bombArray.length - 1) + '].run()', 50);
        }

        /** 刷新游戏地图 */
        function flashMap () {
            ctx.fillStyle = '#eee';
            ctx.fillRect(0, 0, 400, 500);

            drawPeople(people);

            catchMoney();
            catchBomb();

            drawMoney();
            drawBomb();
            drawBoom();
        }

        function drawPeople (people) {
            people.isLive && ctx.drawImage(peopleImg, 0, 0, 780, 1070, people.x, people.y, people.w, people.h);
        }

        function drawMoney () {
            moneyArray.forEach(function(item) {
                if (item.isLive) {
                    ctx.drawImage(yuanbao, 0, 0, 512, 512, item.x, item.y, item.w, item.h);
                }
            })
        }

        function drawBomb () {
            bombArray.forEach(function (bomb) {
                if (bomb.isLive) {
                    ctx.drawImage(bombImg, 160, 160, 480, 480, bomb.x, bomb.y, bomb.w, bomb.h);
                }
            })
        }

        /** 画接住炸弹的爆炸过程 */
        function drawBoom () {
            boomArray.forEach(function(boom) {
                if (boom.isLive) {
                    ctx.drawImage(boomImg, boom.blood * 64, 0, 64, 64, boom.x, boom.y, people.w, people.h);
                    boom.bloodUp();
                } else {
                    // 将爆炸过程画完再游戏结束清空画布
                    gameOver();
                }
            })
        }

        /** 接住礼物 */
        function catchMoney () {
            moneyArray.forEach(function(item) {
                if (item.isLive) {
                    if (isCatch(item)) {
                        people.score += item.score;
                        item.isLive = false;
                        window.clearInterval(item.timer);
                        flashScore();
                    }
                }
            })
        }

        /** 接住了炸弹 */
        function catchBomb () {
            bombArray.forEach(function (bomb) {
                if (bomb.isLive) {
                    if (isCatch(bomb)) {
                        bomb.isLive = false;
                        people.isLive = false;
                        window.clearInterval(bomb.timer);
                        var boom = new Boom(people.x, people.y);
                        boomArray.push(boom);
                    }
                }
            })
        }

        /** 判断物品（礼物、炸弹）有没有进入小人范围 */
        function isCatch (item) {
            return (item.x + (item.w / 2) <= people.x + people.w && item.x + (item.w / 2) >= people.x && item.y + (item.h / 2) <= people.y + people.h && item.y + (item.h / 2) >= people.y);
        }

        /** 刷新积分 */
        function flashScore () {
            var score = document.getElementById('score');
            score.innerHTML = '积分: ' + people.score;
        }

        /** 游戏结束 */
        function gameOver () {
            /** 游戏结束关闭所有定时器 */
            window.clearInterval(moneyTimer);
            window.clearInterval(bombTimer);
            window.clearInterval(flashTimer);

            moneyArray.forEach(function (item) {
                clearInterval(item.timer)
            })

            bombArray.forEach(function (item) {
                clearInterval(item.timer)
            })

            ctx.fillStyle = '#eee';
            ctx.fillRect(0, 0, 400, 500);

            ctx.font = '50px Verdana';
            var gradient = ctx.createLinearGradient(0, 0, 500, 0);
            gradient.addColorStop('0', 'magenta');
            gradient.addColorStop('0.5', 'blue');
            gradient.addColorStop('1', 'red');

            ctx.fillStyle = gradient;
            ctx.fillText('GAME OVER!', 50, 200);
        }

        onload = function () {
            var canvas = document.getElementById('canvas');
            ctx = canvas.getContext('2d');
            ctx.fillStyle = '#eee';
            ctx.fillRect(0, 0, 400, 500);

            peopleImg = document.getElementById('people');
            yuanbao = document.getElementById('money');
            bombImg = document.getElementById('bomb');
            boomImg = document.getElementById('boom');

            for (var i = 0; i < 2; i++) {
                var money = new Money(Math.random() * (400 - 32), 0, 5, 40, 40);
                moneyArray.push(money);
                window.setInterval('moneyArray[' + i + '].run()', 50);
            }

            moneyTimer = window.setInterval('moneyFactory()', 5000);
            bombTimer = window.setInterval('bombFactory()', 10000);
            flashTimer = window.setInterval('flashMap()', 50);
        }

        /** 键盘事件 */
        document.onkeydown = function () {
            var e = event || window.event || arguments.callee.caller.arguments[0];
            var flag = true;
            switch (e.keyCode) {
                case 37:
                    if (people.x > 0) {
                        people.moveLeft();
                    }
                    break;
                case 39:
                    if (people.x + people.w < 400) {
                        people.moveRight();
                    }
                    break;
                default:
                    flag = false;
                    break;
            }
            flag && flashMap();
        }
    </script>
</head>
<body>
    <h1 id="score">积分: 0</h1>
    <canvas id="canvas" width="400" height="500"></canvas>
    <img id="people" src="img/people.png">
    <img id="money" src="img/liwu.png">
    <img id="bomb" src="img/bomb.png">
    <img id="boom" src="img/boom.png">
</body>
</html>